Skip to content

tonic-xds: Implement subchannel state machine#2587

Merged
gu0keno0 merged 7 commits intohyperium:masterfrom
gu0keno0:channel-states
Apr 15, 2026
Merged

tonic-xds: Implement subchannel state machine#2587
gu0keno0 merged 7 commits intohyperium:masterfrom
gu0keno0:channel-states

Conversation

@gu0keno0
Copy link
Copy Markdown
Collaborator

@gu0keno0 gu0keno0 commented Apr 11, 2026

Implement the type-statemachine for load balancer subchannels. This is preparing for implementing the actual load balancer.

Ref: #2444

Motivation

A real world xDS load-balancer needs to deal with outlier detection and reconnects. Therefore, subchannels managed by load balancer needs to implement a state machine. This PR implements it via type-states.

In the next PR, the load balancer tower layer will drive the state transitions in its poll_ready() implementation. This way, we get full control and visibility in to the managed channels. Therefore, we opens up the flexibility of implementing different LB strategies (e.g. sticky, round-robin, etc), compared to the hardcoded P2C stategy offered by tower::balance that we are currently using.

Solution

Define new type for each state, state transition is implemented by consuming the type for the source state. ConnectingChannel and EjectedChannel needs to be implemented as Streams so that load balancer can use StreamMap to poll them to advance their state transitions.

@gu0keno0 gu0keno0 marked this pull request as ready for review April 11, 2026 03:34
@gu0keno0 gu0keno0 marked this pull request as draft April 12, 2026 16:49
@gu0keno0
Copy link
Copy Markdown
Collaborator Author

WIP, will replace stream with futures, because streammap's poll is O(N).

@gu0keno0 gu0keno0 marked this pull request as ready for review April 14, 2026 18:19
Req: Send + 'static,
{
type Response = S::Response;
type Error = BoxError;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not S::Future and S::Error?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's because ReadyChannel.inner is LbChannel, and LbChannel wraps S::future so that in-flight guard can be used.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

still S::future and S::Error should work right? let inner make decision about its type?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Originally ReadyChannel wraps a fixed type of LbChannel, which returns BoxFuture and BoxError.

Now I've changed it and let ReadyChannel just wraps generic S, so it can now use S::Future.

Copy link
Copy Markdown
Collaborator

@ankurmittal ankurmittal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rest LGTM

@gu0keno0 gu0keno0 merged commit 3edd872 into hyperium:master Apr 15, 2026
21 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants